package org.xtremeobjects.forms.ui.editors;

import java.util.Collection;
import java.util.List;

import javax.naming.OperationNotSupportedException;

import org.xtremeobjects.domain.model.Clazz;
import org.xtremeobjects.domain.model.ClazzFactoryImpl;
import org.xtremeobjects.domain.model.ClazzRepository;
import org.xtremeobjects.domain.model.Property;
import org.xtremeobjects.domain.model.ddd.Factory;
import org.xtremeobjects.domain.model.ddd.IAgregate;
import org.xtremeobjects.domain.model.ddd.IModule;
import org.xtremeobjects.domain.model.ddd.ModuleRepository;
import org.xtremeobjects.domain.model.ddd.Repository;


import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;

public class CollectionEditorModel {

	private Clazz clazzModel;
	private Repository repository;
	private Factory factory;
	private List collection = null;
	private ClazzRepository clazzRepository;

	@AssistedInject
	CollectionEditorModel( @Assisted Class clazz, ClazzRepository clazzRepository, ModuleRepository moduleRepository )
	{
		this.clazzRepository = clazzRepository;
		this.setClazzModel(clazzRepository.findOrCreateByClass(clazz));
		IModule module = moduleRepository.getModuleForClazz(getClazzModel());
		IAgregate agregate = module.getAgregateForClazz( getClazzModel() ); 
		this.repository = agregate.getRepository();
		this.factory = agregate.getFactory();
	}

	public String[] getPropertiesNames() {
		return getClazzModel().getPropertiesNames();
	}
	
	public List<Property> getProperties() {
		return getClazzModel().getProperties();
	}

	public List getCollection() {
//		if(collection == null )
		    collection = repository.allInstances();
		return collection;
	}

	public void add(Object obj) {
		repository.addObject(obj);
		getCollection().add(obj);
	}

	public void createNew() throws OperationNotSupportedException {
		if(!canCreateNew())
			throw new OperationNotSupportedException("Create new not Supported");

		Object obj = factory.createNew();
		add( obj );
	}

	public void remove(Object obj) throws OperationNotSupportedException {
		if(!canRemove())
			throw new OperationNotSupportedException("Remove not Supported");

		repository.removeObject(obj);
		getCollection().remove(obj);
	}

	public void remove(Collection objs) throws OperationNotSupportedException {
		if(!canRemove())
			throw new OperationNotSupportedException("Remove not Supported");

		repository.removeObject(objs);
		getCollection().removeAll(objs);
	}

	public boolean canAdd() {
		return repository.canAdd();
	}
	
	public boolean canCreateNew()
	{
		if(factory==null)
			return false;
		return factory.canCreateNew();
	}

	public boolean canRemove()
	{
		return repository.canRemove();
	}

	public Class getImplementationClass() {
		return getClazzModel().getImplementationClass();
	}

	private void setClazzModel(Clazz clazzModel) {
		this.clazzModel = clazzModel;
	}

	public Clazz getClazzModel() {
		return clazzModel;
	}
	
}
